<template>
  <div>
    <el-card shadow="always" :body-style="{ padding: '20px' }">
      <el-row :gutter="20">
        <el-col :span="4" :xs="24" :offset="0">
          <div class="head-container">
            <el-input
              v-model="deptName"
              placeholder="请输入部门名称"
              clearable
              size="small"
              prefix-icon="el-icon-search"
              style="margin-bottom: 20px"
            />
          </div>
          <div class="head-container">
            <el-tree
              ref="deptTree"
              :data="deptTreeData"
              :props="deptDefaultProps"
              :expand-on-click-node="false"
              :filter-node-method="filterNode"
              default-expand-all
              @node-click="handleNodeClick"
            /></div
        ></el-col>
        <!--用户数据-->
        <el-col :span="20" :xs="24">
          <el-form
            ref="searchRef"
            :model="seachData"
            :inline="true"
            label-width="68px"
          >
            <el-form-item label="用户名称" prop="username">
              <el-input
                v-model="seachData.username"
                placeholder="请输入用户名称"
                clearable
                size="small"
                style="width: 160px"
                @keyup.enter.native="initPage"
              />
            </el-form-item>
            <el-form-item label="手机号码" prop="phone">
              <el-input
                v-model="seachData.phone"
                placeholder="请输入手机号码"
                clearable
                size="small"
                style="width: 160px"
                @keyup.enter.native="initPage"
              />
            </el-form-item>
            <el-form-item label="状态" prop="status">
              <el-select
                v-model="seachData.status"
                placeholder="在线状态"
                clearable
                size="small"
                style="width: 160px"
              >
                <el-option
                  v-for="dict in statusOptions"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button
                type="primary"
                icon="search"
                size="small"
                @click="initPage"
                >搜索</el-button
              >
              <el-button icon="refresh" size="small" @click="resetQuery"
                >重置</el-button
              >
            </el-form-item>
          </el-form>

          <el-row :gutter="10" class="mb8">
            <el-col :span="1.5">
              <el-button
                type="primary"
                plain
                icon="plus"
                size="small"
                @click="addUser"
                >新增</el-button
              >
            </el-col>
            <el-col :span="1.5">
              <el-button
                type="danger"
                plain
                icon="delete"
                size="small"
                @click="onDelete"
                :disabled="!multipleSelection.length"
                >删除</el-button
              >
            </el-col>
          </el-row>
          <el-row class="mt-2">
            <el-table
              v-loading="loading"
              :data="userList"
              tooltip-effect="dark"
              row-key="id"
              empty-text="暂无数据"
              @selection-change="handleSelectionChange"
            >
              <el-table-column align="left" type="selection" width="55" />
              <el-table-column label="用户名" width="150" prop="userName" />
              <el-table-column label="昵称" prop="nickName" width="120" />
              <el-table-column
                label="部门"
                align="center"
                prop="departmentName"
                width="120"
              />
              <el-table-column
                label="手机号"
                align="center"
                prop="phone"
                width="150"
              >
                <template #default="scope">
                  <span v-if="scope.row.phone == ''">-</span>
                </template>
              </el-table-column>
              <el-table-column label="启用状态" width="80px">
                <template #default="scope">
                  <el-switch
                    v-model="scope.row.enable"
                    :active-value="enable"
                    :inactive-value="notenable"
                    :before-change="beforeChange.bind(this, scope.row)"
                    @change="handleStatusChange(scope.row)"
                  />
                </template>
              </el-table-column>
              <el-table-column align="center" label="状态">
                <template v-slot="scope">
                  <div
                    :class="{
                      'success-dot': scope.row.status == 1,
                      'gray-dot': scope.row.status == 2,
                      'error-dot':
                        scope.row.status != 1 && scope.row.status != 2,
                    }"
                  ></div>
                  <span
                    v-if="scope.row.status == 1"
                    :class="{
                      'success-status': scope.row.status == 1,
                      'gray-status': scope.row.status == 2,
                      'error-status':
                        scope.row.status != 1 && scope.row.status != 2,
                    }"
                    >在线</span
                  >
                  <span
                    v-else
                    :class="{
                      'success-status': scope.row.status == 1,
                      'gray-status': scope.row.status == 2,
                      'error-status':
                        scope.row.status != 1 && scope.row.status != 2,
                    }"
                    >离线</span
                  >
                </template>
              </el-table-column>
              <el-table-column align="left" label="用户角色" min-width="150">
                <template #default="scope">
                  <el-cascader
                    placeholder="绑定角色"
                    v-model="scope.row.authorityIds"
                    style="width: 100%"
                    :options="authOptions"
                    :show-all-levels="false"
                    collapse-tags
                    :props="{
                      multiple: true,
                      checkStrictly: true,
                      label: 'authorityName',
                      value: 'authorityId',
                      disabled: 'disabled',
                      emitPath: false,
                    }"
                    :clearable="false"
                    @visible-change="
                      (flag) => {
                        changeAuthority(scope.row, flag, 0);
                      }
                    "
                    @remove-tag="
                      (removeAuth) => {
                        changeAuthority(scope.row, false, removeAuth);
                      }
                    "
                  />
                </template>
              </el-table-column>
              <el-table-column label="操作" width="250">
                <template #default="scope">
                  <el-button
                    size="small"
                    type="primary"
                    link
                    @click="openEdit(scope.row)"
                    >修改</el-button
                  >
                  <el-button
                    size="small"
                    type="primary"
                    link
                    @click="deleteUserFunc(scope.row)"
                    :disabled="scope.row.userName == 'admin'"
                    >删除</el-button
                  >
                  <el-button
                    size="small"
                    type="primary"
                    link
                    @click="resetPasswordFunc(scope.row)"
                    >重置密码</el-button
                  >
                </template>
              </el-table-column>
            </el-table>
          </el-row>
          <div class="gva-pagination mt-2">
            <el-pagination
              :current-page="seachData.page"
              :page-size="seachData.pageSize"
              :page-sizes="[10, 30, 50, 100]"
              :total="total"
              layout="total, sizes, prev, pager, next, jumper"
              @current-change="handleCurrentChange"
              @size-change="handleSizeChange"
            />
          </div>
        </el-col>
      </el-row>
    </el-card>
    <!-- 添加 编辑用户 -->
    <el-dialog
      v-model="addUserDialog"
      title="用户"
      :show-close="false"
      :close-on-press-escape="false"
      :close-on-click-modal="false"
    >
      <div style="overflow: auto; padding: 0 12px">
        <el-form
          ref="userForm"
          :rules="rules"
          :model="userInfo"
          label-width="80px"
        >
          <el-form-item
            v-if="dialogFlag === 'add'"
            label="用户名"
            prop="userName"
          >
            <el-input v-model="userInfo.userName" />
          </el-form-item>
          <el-form-item
            v-if="dialogFlag === 'add'"
            label="密码"
            prop="password"
          >
            <el-input v-model="userInfo.password" />
          </el-form-item>
          <el-form-item label="昵称" prop="nickName">
            <el-input v-model="userInfo.nickName" />
          </el-form-item>
          <el-form-item label="手机号" prop="phone">
            <el-input v-model="userInfo.phone" />
          </el-form-item>
          <el-form-item label="邮箱" prop="email">
            <el-input v-model="userInfo.email" />
          </el-form-item>
          <el-form-item label="部门" prop="departmentId">
            <el-select
              placeholder="部门"
              v-model="deptOptionsActiveKey"
              size="small"
            >
              <el-option
                v-for="dict in deptOptions"
                :key="dict.deptId"
                :label="dict.deptName"
                :value="dict.deptId"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="用户角色" prop="authorityId">
            <el-cascader
              v-model="userInfo.authorityIds"
              size="small"
              placeholder="绑定角色"
              :options="authOptions"
              :show-all-levels="false"
              :props="{
                multiple: true,
                checkStrictly: true,
                label: 'authorityName',
                value: 'authorityId',
                disabled: 'disabled',
                emitPath: false,
              }"
              :clearable="false"
            />
          </el-form-item>
          <el-form-item label="启用" prop="disabled">
            <el-switch
              v-model="userInfo.enable"
              inline-prompt
              :active-value="1"
              :inactive-value="2"
            />
          </el-form-item>
        </el-form>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button size="small" @click="closeAddUserDialog">取 消</el-button>
          <el-button size="small" type="primary" @click="doAddOrUpdate"
            >确 定</el-button
          >
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, watch, nextTick } from "vue";
import {
  getDeptPageUsers,
  lockUser,
  registerUser,
  deleteUser,
  deleteUsers,
  resetPassword,
  GetDeptByPage,
  updateUserInfo,
  setUserAuthorities,
} from "~/api/manager";
import { getDeptTree } from "~/api/deparment";
import { getAuthorityList } from "~/api/authority";
import { message } from "~/utils/utils.js";
import { _throttle } from "~/utils/_throttle.js";
import { useUserCenter } from "~/pinia/useUserCenter.js";
import { ElMessageBox } from "element-plus";

// 节流

// 分页相关
const total = ref(10);
// 组织树相关
const deptName = ref("");
const deptTreeData = ref([]);
const deptTree = ref(null);

watch(deptName, (val) => {
  deptTree.value.filter(val);
});

// 筛选节点
const filterNode = (value, data) => {
  if (!value) return true;
  return data.deptName.indexOf(value) !== -1;
};

const handleNodeClick = (row) => {
  deptID.value = row.deptId;
  initPage();
};

const deptDefaultProps = ref({
  children: "children",
  label: "deptName",
});

// 用户列表相关
// enable 1为启用 2为禁用
const enable = ref(1);
const notenable = ref(2);
const userList = ref([]);
const loading = ref(true);
const seachData = ref({
  username: "",
  phone: "",
  status: "",
  page: 1,
  pageSize: 10,
});
const deptID = ref(1);
const authOptions = ref([]);
// 用于设置下拉框的全部角色
const setOptions = (authData) => {
  authOptions.value = [];
  setAuthorityOptions(authData, authOptions.value);
};

// 用于设置authorityIds来绑定el-cascader
watch(
  () => userList.value,
  () => {
    setAuthorityIds();
  }
);
const setAuthorityIds = () => {
  userList.value &&
    userList.value.forEach((user) => {
      const authorityIds =
        user.authorities &&
        user.authorities.map((i) => {
          return i.authorityId;
        });
      user.authorityIds = authorityIds;
    });
};

// 初始化相关
const setAuthorityOptions = (AuthorityData, optionsData) => {
  AuthorityData &&
    AuthorityData.forEach((item) => {
      if (item.children && item.children.length) {
        const option = {
          authorityId: item.authorityId,
          authorityName: item.authorityName,
          children: [],
        };
        setAuthorityOptions(item.children, option.children);
        optionsData.push(option);
      } else {
        const option = {
          authorityId: item.authorityId,
          authorityName: item.authorityName,
        };
        optionsData.push(option);
      }
    });
};

// 用户列表添加节流
const initPage = _throttle(async () => {
  initUser();
  getDeptByPage();
  const res = await getAuthorityList({ page: 1, pageSize: 999 });
  setOptions(res.list);
}, 100);

const init = async () => {
  const res = await getDeptTree();
  if (res) {
    deptTreeData.value = res;
  }
};

const initUser = async () => {
  loading.value = true;
  const Userstatus = parseInt(seachData.value.status);
  const res = await getDeptPageUsers(deptID.value, {
    page: seachData.value.page,
    pageSize: seachData.value.pageSize,
    username: seachData.value.username,
    status: Userstatus,
    phone: seachData.value.phone,
  });
  if (res) {
    total.value = res.total;
    seachData.value.pageSize = res.pageSize;
    seachData.value.page = res.page;
    userList.value = res.list;
    loading.value = false;
  }
};

// 增加 修改用户相关
// 检验规则
const rules = ref({
  userName: [{ required: true, message: "请输入用户名", trigger: "blur" }],
  password: [{ required: true, message: "请输入用户密码", trigger: "blur" }],
  nickName: [{ required: true, message: "请输入用户昵称", trigger: "blur" }],
  phone: [
    // 这个只能验证手机号
    {
      pattern: /^1([38][0-9]|4[014-9]|[59][0-35-9]|6[2567]|7[0-8])\d{8}$/,
      message: "请输入合法手机号",
      trigger: "blur",
    },
  ],
  email: [
    {
      pattern: /^([0-9A-Za-z\-_\.]+)@([0-9a-z]+\.[a-z]{2,3}(\.[a-z]{2})?)$/g,
      message: "请输入正确的邮箱",
      trigger: "blur",
    },
  ],
  authorityId: [{ required: true, message: "请选择用户角色", trigger: "blur" }],
});

// 弹窗相关
const userInfo = ref({
  username: "",
  password: "",
  nickName: "",
  authorityId: "",
  authorityIds: [],
  departmentId: 1,
  enable: 1,
});

// 关闭弹窗
const userForm = ref(null);
const dialogFlag = ref("add");
const addUserDialog = ref(false);

const closeAddUserDialog = () => {
  userForm.value.resetFields();
  userInfo.value.authorityIds = [];
  addUserDialog.value = false;
};

const addUser = () => {
  dialogFlag.value = "add";
  addUserDialog.value = true;
};

const openEdit = (row) => {
  dialogFlag.value = "edit";
  deptOptionsActiveKey.value = row.departmentId;
  userInfo.value = JSON.parse(JSON.stringify(row));
  addUserDialog.value = true;
};

const doAddOrUpdate = () => {
  userInfo.value.authorityId = userInfo.value.authorityIds[0];
  userInfo.value.departmentId = deptOptionsActiveKey.value;
  userForm.value.validate(async (valid) => {
    if (valid) {
      const req = {
        ...userInfo.value,
      };
      switch (dialogFlag.value) {
        case "add":
          const res = await registerUser(req);
          if (res) {
            message(res);
            initPage();
          }
          closeAddUserDialog();
          break;
        case "edit":
          const editres = await updateUserInfo(req);
          if (editres) {
            message(editres);
            initPage();
          }
          closeAddUserDialog();
          break;
      }
    }
  });
};

// 列表更改用户权限
const tempAuth = {};
const changeAuthority = async (row, flag, removeAuth) => {
  if (flag) {
    if (!removeAuth) {
      tempAuth[row.ID] = [...row.authorityIds];
    }
    return;
  }
  await nextTick();
  const res = await setUserAuthorities(row.id, {
    authorityIds: row.authorityIds,
  });
  if (res) {
    message(res);
  } else {
    if (!removeAuth) {
      row.authorityIds = [...tempAuth[row.ID]];
      delete tempAuth[row.ID];
    } else {
      row.authorityIds = [removeAuth, ...row.authorityIds];
    }
  }
};

// 删除用户
const deleteUserFunc = (row) => {
  ElMessageBox.confirm("是否删除此用户?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    const res = await deleteUser(row.id);
    if (res) {
      message(res);
      initPage();
    }
  });
};

// 重置密码
const resetPasswordFunc = (row) => {
  ElMessageBox.confirm("是否将此用户密码重置为kubemanage?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    const res = await resetPassword(row.id);
    if (res) {
      message(res);
    }
  });
};

// 禁用用户
const beforeChange = (row) => {
  return new Promise((resolve, reject) => {
    // 判断当前登录用户是否为操作用户，禁止锁定当前登录用户
    const user = useUserCenter();
    if (user.user.userName === row.userName) {
      message("禁止禁用当前登录用户", "error");
      return reject(new Error("禁止禁用当前登录用户"));
    } else {
      resolve(true);
    }
  });
};
const handleStatusChange = async (row) => {
  // 1为启用，2禁用用户
  switch (row.enable) {
    case 1:
      const unlockRes = await lockUser(row.id, "unlock");
      if (unlockRes) {
        message(unlockRes);
        break;
      }
    case 2:
      const lockRes = await lockUser(row.id, "lock");
      if (lockRes) {
        message(lockRes);
        break;
      }
  }
};

const statusOptions = ref([
  { value: "1", label: "在线" },
  { value: "2", label: "离线" },
]);

// 部门相关
const deptOptionsActiveKey = ref(1);
const deptOptions = ref([]);
const getDeptByPage = async () => {
  const res = await GetDeptByPage({
    page: 1,
    pageSize: 9999,
  });
  deptOptions.value = res.list;
};

// 重置搜索表单
const searchRef = ref(null);
const resetQuery = () => {
  searchRef.value.resetFields();
  initPage();
};

// 分页相关

const handleSizeChange = (val) => {
  seachData.value.pageSize = val;
  initPage();
};

const handleCurrentChange = (val) => {
  seachData.value.page = val;
  initPage();
};

// 批量删除相关
const multipleSelection = ref([]);
const handleSelectionChange = (val) => {
  multipleSelection.value = val;
};

const onDelete = async () => {
  ElMessageBox.confirm("是否删除多个用户?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    const ids = [];
    multipleSelection.value &&
      multipleSelection.value.forEach((item) => {
        ids.push(item.id);
      });
    const res = await deleteUsers({ ids });
    if (res) {
      message(res);
      initPage();
    }
  });
};
// 真正调用

init();
initPage();
</script>

<style lang="scss" scoped>
.user-dialog {
  .header-img-box {
    width: 200px;
    height: 200px;
    border: 1px dashed #ccc;
    border-radius: 20px;
    text-align: center;
    line-height: 200px;
    cursor: pointer;
  }
}
.success-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  background: rgb(104, 221, 93);
  border-radius: 50%;
  border: 1px solid rgb(104, 221, 93);
  margin-right: 10px;
}
.gray-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  background: rgb(150, 148, 143);
  border-radius: 50%;
  border: 1px solid rgb(150, 148, 143);
  margin-right: 10px;
}
.error-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  background: rgb(226, 23, 23);
  border-radius: 50%;
  border: 1px solid rgb(226, 23, 23);
  margin-right: 10px;
}
.success-status {
  color: rgb(27, 202, 21);
}
.gray-status {
  color: rgb(150, 148, 143);
}
.error-status {
  color: rgb(226, 23, 23);
}
</style>
